package com.bj.disc.util

/**
 * 播放器控制类  不写任何业务代码只是播放器
 */
import kotlin.math.min
import android.content.Context
import android.net.Uri
import com.ai3d.rfid.common.log.Logcat
import com.ai3d.rfid.common.proxy.MMKVProxy
import com.ai3d.rfid.common.proxy.ToastProxy
import com.ai3d.rfid.common.utils.HandlerUtils
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.analytics.AnalyticsListener
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
import com.google.android.exoplayer2.source.ExtractorMediaSource
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.TrackGroupArray
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.trackselection.TrackSelectionArray
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.ym521.logdog.LogDog
import org.greenrobot.eventbus.EventBus
import java.io.File


class PlayerManager(private val context: Context) {
    private val tag = PlayerManager::class.java.simpleName

    private val exoPlayer = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector())

    private var isPlaying: Boolean = false
    private var loopCount: Int = 0
    private var loopInterval: Long = 0
    private var currentLoopCount: Int = 0
    private var playbackRunnable: Runnable? = null
    private var mediaSourceList: MutableList<MediaSource> = mutableListOf()
    private var realUrls: MutableList<String> = mutableListOf()
    private var callback: AudioPlayerCallback? = null

    private var lastLanguage = ""//上次播放的语言 这绝对当前播放语言应该从什么语言开始

    private var languageMap = HashMap<String, String>()

    fun setCallback(callback: AudioPlayerCallback) {
        this.callback = callback
    }


    init {
        languageMap.put(DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US, FileConstant.english)
        languageMap.put(DiscConstants.HEADER_CONTENT_LANGUAGE_ZH_CN, FileConstant.china)
        languageMap.put(DiscConstants.HEADER_CONTENT_LANGUAGE_HOKKIEN, FileConstant.Hokkien)
        languageMap.put(DiscConstants.HEADER_CONTENT_LANGUAGE_CANTONESE, FileConstant.Cantonese)
        languageMap.put(DiscConstants.HEADER_CONTENT_LANGUAGE_TAMIL, FileConstant.Tamil)
        languageMap.put(DiscConstants.HEADER_CONTENT_LANGUAGE_MALAY, FileConstant.Malay)
        exoPlayer.addListener(object : Player.EventListener {

            override fun onTracksChanged(
                trackGroups: TrackGroupArray,
                trackSelections: TrackSelectionArray
            ) {
                super.onTracksChanged(trackGroups, trackSelections)

                println("onTracksChanged============" + exoPlayer.getCurrentTag())
                if (exoPlayer?.currentTag?.toString()?.isNotEmpty() == true) {
                    EventBus.getDefault().post(exoPlayer.getCurrentTag().toString())
                }
                if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.english) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Hokkien) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_HOKKIEN
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Cantonese) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_CANTONESE
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Tamil) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_TAMIL
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Malay) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_MALAY
                }
                else {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_ZH_CN
                }
            }


            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
                when (playbackState) {
                    Player.STATE_IDLE -> {
                        // 播放器处于空闲状态
                        Logcat.d(tag, "播放器处于空闲状态")
                    }

                    Player.STATE_BUFFERING -> {
                        // 播放器正在缓冲数据
                        Logcat.d(tag, "播放器正在缓冲数据")
                    }

                    Player.STATE_READY -> {
                        // 播放器已准备好播放

                        println("播放器已准备好播放")
                        Logcat.d(tag, "播放器已准备好播放")
                        if (playWhenReady) {
                            // 播放器正在播放
                            callback?.onPlaybackStarted()
                            Logcat.d(tag, "播放器正在播放")
                        } else {
                            // 播放器已暂停
                            Logcat.d(tag, "播放器已暂停")
                        }
                    }

                    Player.STATE_ENDED -> {
                        // 播放完成
                        Logcat.d(tag, "播放完成")
                        callback?.onPlaybackCompleted()
                        HandlerUtils.postDelayed(playbackRunnable!!, loopInterval)
                    }
                }
            }

            override fun onPlayerError(error: ExoPlaybackException) {
                var file = File(exoPlayer.getCurrentTag().toString())
                ToastProxy.showLong(
                    "资源匹配失败:路径" + exoPlayer.getCurrentTag()
                        .toString() + "路径是否存在：${file.exists()} exception:" + error.message
                )
                // 播放出错
                Logcat.d(tag, "播放出错")
                LogDog.debug(
                    tag,
                    "资源匹配失败:路径" + exoPlayer.getCurrentTag()
                        .toString() + "路径是否存在：${file.exists()} exception:" + error.message
                )
                callback?.onPlaybackError(error)
                if (loopCount > 0) {
                    exoPlayer.stop();
                    // 重置播放器
                    exoPlayer.seekToDefaultPosition();
                    HandlerUtils.postDelayed(playbackRunnable!!, loopInterval)
                }
            }
        })
        exoPlayer.addAnalyticsListener(object : AnalyticsListener {

        })
    }

    fun play(filePath: String, fileName: List<String>, isSeekToIndexFirst: Boolean? = true) {
        mediaSourceList.clear()
        realUrls.clear()
        HandlerUtils.removeCallbacksAndMessages()
        var urls = ArrayList<String>()
        sortAddList(filePath, fileName, urls)
        urls.forEach {
            Logcat.d("xxxxxxxxxxxxxx", "it : $it")
        }

        realUrls.addAll(urls)
        val concatenatedSource = buildConcatenatingMediaSource(urls)
        exoPlayer.prepare(concatenatedSource)
        exoPlayer.playWhenReady = true

        isPlaying = true
        currentLoopCount = 0
        // 如果需要循环播放
        playbackRunnable = object : Runnable {
            override fun run() {
                if (loopCount > 0) {
                    if (isPlaying) {
                        currentLoopCount++
                        if (currentLoopCount <= loopCount) {
                            if (isSeekToIndexFirst == true) {
                                seekTo(0)
                            } else {
                                exoPlayer.seekTo(0)
                            }
                            exoPlayer.playWhenReady = true
                        } else {
                            pauseAudio()
                        }
                    }
                }
            }
        }
    }

    fun playHard(filePath: String, fileName: List<String>, isSeekToIndexFirst: Boolean? = true) {
        mediaSourceList.clear()
        realUrls.clear()
        HandlerUtils.removeCallbacksAndMessages()
        var urls = ArrayList<String>()
        sortHard(filePath, fileName, urls)
        realUrls.addAll(urls)
        val concatenatedSource = buildConcatenatingMediaSource(urls)
        exoPlayer.prepare(concatenatedSource)
        exoPlayer.playWhenReady = true

        isPlaying = true
        currentLoopCount = 0
        // 如果需要循环播放
        playbackRunnable = object : Runnable {
            override fun run() {
                if (loopCount > 0) {
                    if (isPlaying) {
                        currentLoopCount++
                        if (currentLoopCount <= loopCount) {
                            if (isSeekToIndexFirst == true) {
                                seekTo(0)
                            } else {
                                exoPlayer.seekTo(0)
                            }
                            exoPlayer.playWhenReady = true
                        } else {
                            pauseAudio()
                        }
                    }
                }
            }
        }
    }

    private fun sortHard(filePath: String, fileName: List<String>, urls: ArrayList<String>) {
        fileName.forEachIndexed { index, it ->
            urls.add(FilePath.rootDir + filePath + "/" + it)
        }
    }

    //两个语言是否选择一样的
    fun isSameLan(): Boolean {
        var same = MMKVProxy.getString(
            MMKVProxy.KEY_SETTINGS_LANGUAGE_ASSIST,
            DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
        ).equals(
            MMKVProxy.getString(
                MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
            ), true
        )
        return same
    }

    private fun sortAddList(filePath: String, fileName: List<String>, urls: ArrayList<String>) {
        //判断两个语言是否选择一样的

        //只有是两种语言不一样 才需要考虑切换语言的问题
        if (!isSameLan()) {
            //如果它是英文 那就要从中文开始
            if (lastLanguage.equals(
                    MMKVProxy.getString(
                        MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                        DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                    )
                )
            ) {
                fileName.forEachIndexed { index, it ->
                    if (index % 2 == 0) {
                        urls.add(
                            FilePath.rootDir + filePath + languageMap.get(
                                MMKVProxy.getString(
                                    MMKVProxy.KEY_SETTINGS_LANGUAGE_ASSIST,
                                    DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                                )
                            ) + it
                        )
                    } else {
                        urls.add(
                            FilePath.rootDir + filePath + languageMap.get(
                                MMKVProxy.getString(
                                    MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                                    DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                                )
                            ) + it
                        )
                    }
                }
            } else {
                fileName.forEachIndexed { index, it ->
                    if (index % 2 == 0) {
                        urls.add(
                            FilePath.rootDir + filePath + languageMap.get(
                                MMKVProxy.getString(
                                    MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                                    DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                                )
                            ) + it
                        )
                    } else {
                        urls.add(
                            FilePath.rootDir + filePath + languageMap.get(
                                MMKVProxy.getString(
                                    MMKVProxy.KEY_SETTINGS_LANGUAGE_ASSIST,
                                    DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                                )
                            ) + it
                        )
                    }
                }
            }
        } else {
            fileName.forEachIndexed { index, it ->
                urls.add(
                    FilePath.rootDir + filePath + languageMap.get(
                        MMKVProxy.getString(
                            MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                            DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                        )
                    ) + it
                )

            }
        }
    }

    private fun sortAddList(filePath: String, fileName: String, urls: ArrayList<String>) {
        if (!isSameLan()) {
            //如果它是英文 那就要从中文开始
            if (lastLanguage.equals(
                    MMKVProxy.getString(
                        MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                        DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                    )
                )
            ) {
                urls.add(
                    FilePath.rootDir + filePath + languageMap.get(
                        MMKVProxy.getString(
                            MMKVProxy.KEY_SETTINGS_LANGUAGE_ASSIST,
                            DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                        )
                    ) + fileName
                )
            } else {
                urls.add(
                    FilePath.rootDir + filePath + languageMap.get(
                        MMKVProxy.getString(
                            MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                            DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                        )
                    ) + fileName
                )
            }

        } else {
            urls.add(
                FilePath.rootDir + filePath + languageMap.get(
                    MMKVProxy.getString(
                        MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                        DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                    )
                ) + fileName
            )
        }
    }

    fun levenshteinDistance(str1: String, str2: String): Int {
        val dp = Array(str1.length + 1) { IntArray(str2.length + 1) }

        for (i in 0..str1.length) {
            for (j in 0..str2.length) {
                when {
                    i == 0 -> dp[i][j] = j
                    j == 0 -> dp[i][j] = i
                    else -> {
                        val cost = if (str1[i - 1] == str2[j - 1]) 0 else 1
                        dp[i][j] = min(
                            dp[i - 1][j] + 1,
                            min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost)
                        )
                    }
                }
            }
        }

        return dp[str1.length][str2.length]
    }

    fun findImageRecordByName(name: String): List<String> {
        LogDog.debug(tag, "匹配播放图片的文件，用来匹配的文件名称是" + name)
        var newName = ""
        if (name.isNotEmpty() && name.indexOf(".") != -1) {
            newName = name.subSequence(0, name.lastIndexOf(".")) as String
            //去除数字 去除空格 去除下划线
            newName = newName.replace(Regex("[0-9]"), "").replace("_", "").replace(" ", "")
                .replace("(", "").replace(")", "")
        }
        println(name + "===========name==========" + newName)
        LogDog.debug(tag, "匹配播放图片的文件，用来匹配的处理后的名称是" + newName)
        var list = ArrayList<String>()
        var folder: File? = null
        //如果上次播放的是第一语言 这个时候就要添加第二语言的 如果是第二语言的就是要添加第一语言的
        if (lastLanguage.isNotEmpty()) {
            if (lastLanguage.equals(
                    MMKVProxy.getString(
                        MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                        DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                    )
                )
            ) {
                folder =
                    File(
                        "${FilePath.rootDir}${FileConstant.UOT_IMAGES_RECORDING}${
                            languageMap.get(
                                MMKVProxy.getString(
                                    MMKVProxy.KEY_SETTINGS_LANGUAGE_ASSIST,
                                    DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                                )
                            )
                        }"
                    )
                val matchingFiles = folder.listFiles { file ->
                    file.name.trim().contains(newName, true)
                }
                matchingFiles.sortBy { it.name.length }
                if (null != matchingFiles && matchingFiles.size > 0) {
                    list.add(matchingFiles.get(0).path)
                }
            } else {

                folder = File(
                    "${FilePath.rootDir}${FileConstant.UOT_IMAGES_RECORDING}${
                        languageMap.get(
                            MMKVProxy.getString(
                                MMKVProxy.KEY_SETTINGS_LANGUAGE_MAIN,
                                DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                            )
                        )
                    }"
                )
                val matchingFiles = folder.listFiles { file ->
                    file.name.trim().contains(newName, true)
                }
                matchingFiles.sortBy { it.name.length }
                if (null != matchingFiles && matchingFiles.size > 0) {
                    list.add(matchingFiles.get(0).path)
                }
            }
        } else {
            folder =
                File(
                    "${FilePath.rootDir}${FileConstant.UOT_IMAGES_RECORDING}${
                        languageMap.get(
                            MMKVProxy.getString(
                                MMKVProxy.KEY_SETTINGS_LANGUAGE_ASSIST,
                                DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                            )
                        )
                    }"
                )
            val matchingFiles = folder.listFiles { file ->
                file.name.trim().contains(newName, true)
            }
            matchingFiles.sortBy { it.name.length }
            if (null != matchingFiles && matchingFiles.size > 0) {
                list.add(matchingFiles.get(0).path)
            }
        }
        if (list.size == 0 && null != folder && folder?.listFiles()?.size!! > 0) {
            var tempName = name.replace("(", "").replace(")", "").replace(Regex("[0-9]"), "")
            LogDog.debug(tag, folder.path + "播放失败 寻找图片失败 开始重新匹配" + tempName)
            tempName = tempName.substringBeforeLast(".") // 去掉后缀名
            val separator = if (tempName.contains("_")) "_" else " "
            val wordsToMatch = tempName.split(separator)
            var temp = ArrayList<String>()
            wordsToMatch.forEach {
                if (it.trim().length > 0) {
                    temp.add(it)
                }
            }

            val files = folder.listFiles()

            var maxMatchCount = 0
            var bestMatchingFile: File? = null

            if (files != null) {
                for (file in files) {
                    val fileWords = splitCamelCase(file.name.trim().substringBeforeLast("."))
                    val matchCount =
                        fileWords.count { it.toLowerCase() in temp.map { it.toLowerCase() } }

                    if (matchCount > maxMatchCount) {
                        maxMatchCount = matchCount
                        bestMatchingFile = file
                    }
                }
            }
            if (null != bestMatchingFile) {
                LogDog.debug(tag, "播放失败 寻找图片失败 重新匹配成功" + bestMatchingFile?.path)
                bestMatchingFile?.path?.let { list.add(it) }
            } else {
                LogDog.debug(tag, "播放失败 寻找图片失败 重新匹配失败")
            }
        }
        return list
    }

    fun splitCamelCase(input: String): List<String> {
        val regex = "(?=[A-Z])".toRegex()
        return input.split(regex)
    }

    fun play(filePath: String, fileName: String) {
        mediaSourceList.clear()
        realUrls.clear()
        HandlerUtils.removeCallbacksAndMessages()
        var urls = ArrayList<String>()
        //这里有顺序的
        sortAddList(filePath, fileName, urls)
        realUrls.addAll(urls)
        val concatenatedSource = buildConcatenatingMediaSource(urls)

        exoPlayer.prepare(concatenatedSource)
        exoPlayer.playWhenReady = true

        isPlaying = true
        currentLoopCount = 0
        // 如果需要循环播放
        playbackRunnable = object : Runnable {
            override fun run() {
                if (loopCount > 0) {
                    if (isPlaying) {
                        currentLoopCount++
                        if (currentLoopCount <= loopCount) {
                            seekTo(0)
                            exoPlayer.playWhenReady = true
                        } else {
                            pauseAudio()
                        }
                    }
                }
            }
        }
    }

//    fun play(filePath: List<String>, fileName: List<String>) {
//        mediaSourceList.clear()
//        HandlerUtils.removeCallbacksAndMessages()
//        var urls = ArrayList<String>()
//        filePath.forEachIndexed { index, it ->
//            urls.add(FilePath.rootDir + it + FileConstant.china + fileName.get(index))
//        }
//        filePath.forEachIndexed { index, it ->
//            urls.add(FilePath.rootDir + it + FileConstant.english + fileName.get(index))
//        }
//
//        val concatenatedSource = buildConcatenatingMediaSource(urls)
//        exoPlayer.prepare(concatenatedSource)
//        exoPlayer.playWhenReady = true
//
//        isPlaying = true
//        currentLoopCount = 0
//        // 如果需要循环播放
//        playbackRunnable = object : Runnable {
//            override fun run() {
//                if (loopCount > 0) {
//                    if (isPlaying) {
//                        currentLoopCount++
//                        if (currentLoopCount <= loopCount) {
//                            seekTo(0)
//                            exoPlayer.playWhenReady = true
//                        } else {
//                            pauseAudio()
//                        }
//                    }
//                }
//            }
//        }
//    }

    fun play(urls: ArrayList<String>) {
        mediaSourceList.clear()
        HandlerUtils.removeCallbacksAndMessages()
        val concatenatedSource = buildConcatenatingMediaSource(urls)
        exoPlayer.prepare(concatenatedSource)
        exoPlayer.playWhenReady = true
        isPlaying = true
        currentLoopCount = 0
        // 如果需要循环播放
        playbackRunnable = object : Runnable {
            override fun run() {
                if (loopCount > 0) {
                    if (isPlaying) {
                        currentLoopCount++
                        if (currentLoopCount <= loopCount) {
                            seekTo(0)
                            exoPlayer.playWhenReady = true
                        } else {
                            pauseAudio()
                        }
                    }
                }
            }
        }
    }

    fun play(urls: List<String>, callback: AudioPlayerCallback): SimpleExoPlayer {
        mediaSourceList.clear()
        realUrls.clear()
        HandlerUtils.removeCallbacksAndMessages()
        val concatenatingMediaSource = ConcatenatingMediaSource()

        val dataSourceFactory = DefaultDataSourceFactory(context, "newPlayer")
        for (url in urls) {
            val mediaSource =
                ExtractorMediaSource.Factory(dataSourceFactory).setTag(url)
                    .createMediaSource(Uri.parse(url))
            concatenatingMediaSource.addMediaSource(mediaSource)
            mediaSourceList.add(mediaSource)
        }
        LogDog.debug("PlayManger", "正在准备播放的url:" + urls.toString())
        realUrls.addAll(urls)
        val exoPlayer = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector())
        exoPlayer.prepare(concatenatingMediaSource)
        exoPlayer.playWhenReady = true
        exoPlayer.addListener(object : Player.EventListener {
            override fun onTracksChanged(
                trackGroups: TrackGroupArray,
                trackSelections: TrackSelectionArray
            ) {
                super.onTracksChanged(trackGroups, trackSelections)
                LogDog.debug("PlayManger", "onTracksChanged正在播放的url:" + urls.toString())
                println("onTracksChangedImage============" + exoPlayer.getCurrentTag())
                if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.english) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_EN_US
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Hokkien) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_HOKKIEN
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Cantonese) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_CANTONESE
                }else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Tamil) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_TAMIL
                } else if (exoPlayer?.getCurrentTag()?.toString()
                        ?.contains(FileConstant.Malay) == true
                ) {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_MALAY
                }

                else {
                    lastLanguage = DiscConstants.HEADER_CONTENT_LANGUAGE_ZH_CN
                }
            }

            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
                when (playbackState) {
                    Player.STATE_IDLE -> {
                        // 播放器处于空闲状态
                        Logcat.d(tag, "播放器处于空闲状态")
                    }

                    Player.STATE_BUFFERING -> {
                        // 播放器正在缓冲数据
                        Logcat.d(tag, "播放器正在缓冲数据")
                    }

                    Player.STATE_READY -> {
                        // 播放器已准备好播放
                        println("播放器已准备好播放")
                        Logcat.d(tag, "播放器已准备好播放")
                        if (playWhenReady) {
                            // 播放器正在播放
                            callback?.onPlaybackStarted()
                            Logcat.d(tag, "播放器正在播放")
                        } else {
                            // 播放器已暂停
                            Logcat.d(tag, "播放器已暂停")
                        }
                    }

                    Player.STATE_ENDED -> {
                        // 播放完成
                        Logcat.d(tag, "播放完成")
                        callback?.onPlaybackCompleted()
                    }
                }

            }


            override fun onPlayerError(error: ExoPlaybackException) {
                var file = File(exoPlayer.getCurrentTag().toString())
                ToastProxy.showShort(
                    "资源匹配失败:路径" + exoPlayer.getCurrentTag()
                        .toString() + "路径是否存在：${file.exists()} exception:" + error.message
                )
                LogDog.debug(
                    "PlayManger",
                    "播放异常:路径" + exoPlayer.getCurrentTag()
                        .toString() + "路径是否存在：${file.exists()} exception:" + error.message
                )
                // 播放出错
                Logcat.d(tag, "播放出错")
                callback?.onPlaybackError(error)
            }
        })
        return exoPlayer

    }

//    fun play(url: String) {
//        HandlerUtils.removeCallbacksAndMessages()
//        val mediaSource: MediaSource = buildMediaSource(Uri.parse(url))
//        exoPlayer.prepare(mediaSource)
//        exoPlayer.playWhenReady = true
//    }
//
//    fun playLoop(url: String) {
//        HandlerUtils.removeCallbacksAndMessages()
//        val mediaSource: MediaSource = buildMediaSource(Uri.parse(url))
//
//        exoPlayer.prepare(mediaSource)
//        exoPlayer.playWhenReady = true
//
//        isPlaying = true
//        currentLoopCount = 0
//
//        // 如果需要循环播放
//        playbackRunnable = object : Runnable {
//            override fun run() {
//                if (loopCount > 0) {
//                    if (isPlaying) {
//                        currentLoopCount++
//                        if (currentLoopCount <= loopCount) {
//                            exoPlayer.seekTo(0)
//                            exoPlayer.playWhenReady = true
//                        } else {
//                            pauseAudio()
//                        }
//                    }
//                }
//            }
//        }
//    }

    fun seekTo(index: Int) {
        if (index >= 0 && index < mediaSourceList.size) {
            exoPlayer.seekTo(index, 0)
        }
    }

    fun pauseAudio() {
        exoPlayer.stop()
        exoPlayer.playWhenReady = false
        isPlaying = false
        playbackRunnable?.let { HandlerUtils.removeCallbacks(it) }

    }

    fun isPlaying(): Boolean {
        return exoPlayer.isPlaying
    }


    fun resumeAudio() {
        exoPlayer.playWhenReady = true
        isPlaying = true
    }

    fun setLoopCount(loopCount: Int) {
        this.loopCount = loopCount
    }

    fun setLoopInterval(loopInterval: Long) {
        this.loopInterval = loopInterval
    }

    private fun buildConcatenatingMediaSource(urls: ArrayList<String>): ConcatenatingMediaSource {
        val concatenatingMediaSource = ConcatenatingMediaSource()

        val dataSourceFactory = DefaultDataSourceFactory(context, "ExoPlayerSample")
        var fileNotExist = ArrayList<Int>()
        urls.forEachIndexed { index, s ->
            var file = File(s)
            if (file.exists()) {
                LogDog.debug(tag, "(文件存在)正在准备播放的url:" + s)
            } else {
                fileNotExist.add(index)
                LogDog.debug(tag, "(文件不存在)发生异常" + s)
            }
        }
        fileNotExist.forEach {
            LogDog.debug(tag, "开始重新匹配新文件" + it)
            var file = File(urls.get(it))
            var dir = File(file.parent)
            if (dir.isDirectory) {
                var temp = dir.listFiles()?.filter {
                    (it.name.subSequence(
                        0,
                        it.name.lastIndexOf(".")
                    ) as String).equals(
                        file.name.subSequence(
                            0,
                            file.name.lastIndexOf(".")
                        ) as String,
                        true
                    )
                }
                if (null != temp) {
                    if (temp?.size!! > 0) {
                        LogDog.debug(tag, "重新匹配新文件成功" + temp.toString())
                        LogDog.debug(tag, "重新替换文件为" + temp.get(0).path)
                        urls[it] = temp.get(0).path
                    }
                } else {
                    LogDog.debug(tag, "重新匹配新文件失败有找到文件")
                }
            } else {
                LogDog.debug(tag, "重新匹配新文件失败父文件不是一个目录")
            }
            //一般是大小写不同 不会是整个文件名都不同

        }
        for (url in urls) {
            val mediaSource =
                ExtractorMediaSource.Factory(dataSourceFactory).setTag(url)
                    .createMediaSource(Uri.parse(url))
            concatenatingMediaSource.addMediaSource(mediaSource)
            mediaSourceList.add(mediaSource)
        }

        return concatenatingMediaSource
    }


    private fun buildMediaSource(uri: Uri): MediaSource {
        val dataSourceFactory = DefaultDataSourceFactory(context, "ExoPlayerSample")
        return ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri)
    }

    fun release() {
        exoPlayer.release()
        HandlerUtils.removeCallbacksAndMessages()
    }

    interface AudioPlayerCallback {
        fun onPlaybackStarted()
        fun onPlaybackCompleted()
        fun onPlaybackError(error: ExoPlaybackException)
    }

    interface DurationCallback {
        fun duration(duration: Long)

    }
}

